#ifndef __THREAD_HPP__
#define __THREAD_HPP__

#include <iostream>
#include <string>
#include <unistd.h>
#include <functional>
#include <pthread.h>

// 线程模块命名空间
namespace ThreadModule
{
    // 定义函数类型别名：表示线程执行的函数类型
    // 参数：T类型的引用和线程名称
    template<typename T>
    using func_t = std::function<void(T&, std::string name)>;
    // typedef std::function<void(const T&)> func_t;

    // 线程类：封装了pthread线程操作
    template<typename T>
    class Thread
    {
    public:
        // 执行线程函数
        void Excute()
        {
            // 调用用户提供的函数，并传递数据和线程名称
            _func(_data, _threadname);
        }
    public:
        // 构造函数：初始化线程对象
        // 参数func：线程要执行的函数
        // 参数data：要传递给线程函数的数据引用
        // 参数name：线程名称，默认为"none-name"
        Thread(func_t<T> func, T &data, std::string name="none-name")
            : _func(func)      // 存储线程函数
            , _data(data)      // 存储数据引用
            , _threadname(name) // 存储线程名称
            , _stop(true)       // 初始化线程状态为停止
        {}
        
        // 静态线程函数：作为pthread_create的参数
        // 注意：类成员函数默认有this指针，不能直接作为pthread_create的参数
        // 参数args：指向Thread对象的指针
        // 返回值：线程结束时的返回值
        static void *threadroutine(void *args)
        {
            // 将参数转换为Thread对象指针
            Thread<T> *self = static_cast<Thread<T> *>(args);
            // 调用对象的Excute方法执行实际任务
            self->Excute();
            return nullptr;
        }
        // 启动线程
        // 返回值：成功启动返回true，否则返回false
        bool Start()
        {
            // 创建线程，指定线程函数为threadroutine，传递this指针作为参数
            int n = pthread_create(&_tid, nullptr, threadroutine, this);
            if(!n)
            {
                // 线程创建成功，更新状态为运行中
                _stop = false;
                return true;
            }
            else
            {
                // 线程创建失败
                return false;
            }
        }
        
        // 分离线程：线程结束后自动回收资源
        void Detach()
        {
            // 只有线程运行中时才执行分离操作
            if(!_stop)
            {
                pthread_detach(_tid);
            }
        }
        
        // 等待线程结束：阻塞当前线程直到目标线程结束
        void Join()
        {
            // 只有线程运行中时才执行等待操作
            if(!_stop)
            {
                pthread_join(_tid, nullptr);
            }
        }
        
        // 获取线程名称
        // 返回值：线程的名称
        std::string name()
        {
            return _threadname;
        }
        
        // 停止线程：设置线程状态为停止
        // 注意：这只是设置一个标志位，实际线程可能仍在运行
        void Stop()
        {
            _stop = true;
        }
        
        // 析构函数
        ~Thread() {}

    private:
        pthread_t _tid;            // 线程ID
        std::string _threadname;   // 线程名称
        T &_data;                  // 线程要处理的数据引用（为了让所有线程访问同一个全局变量）
        func_t<T> _func;           // 线程要执行的函数
        bool _stop;                // 线程状态标志（true表示停止，false表示运行中）
    };
} // namespace ThreadModule

#endif